package blackberry.util.hotkey;

import java.util.Vector;

import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.CodeModuleManager;
import net.rim.device.api.system.ControlledAccessException;


class DjHotkeyManager{

	private  static int[] handlesCache;
	private  static int handlesLengthCache;
	private  static ApplicationDescriptor appDescrCache;
	
	public static Vector getDescriptorsOf(char hotkey) {
		Vector vec = new Vector();
		saveCache();
		for (int i = 0; i < handlesLengthCache; i++) {
			if (checkLibrary(i)) continue;
			saveCacheForAppdescr(i);
			if (hasNotHotkey(hotkey, appDescrCache)) continue;
			vec.addElement(appDescrCache);
		}
		return vec;
	}
	
	private static void saveCache() {
		handlesCache = getModuleHandles();
		handlesLengthCache = handlesCache.length;
	}
	
	private static void saveCacheForAppdescr(int i) {
		appDescrCache = extractDescriptor(handlesCache[i]);
	}
	
	private static int[] getModuleHandles() {
		return CodeModuleManager.getModuleHandles(false);
	}
	
	private static ApplicationDescriptor extractDescriptor(int handle) {
		return CodeModuleManager.getApplicationDescriptors(handle)[0];
	}

	private static boolean checkLibrary(int i) {
		return CodeModuleManager.isLibrary(handlesCache[i]);
	}
	
	private static boolean hasNotHotkey(char key, ApplicationDescriptor targetApp) {
		try {
			if (isRimApp(targetApp)) {
				return hasNotUnderbarInAppDescription(key, targetApp);
			} else {
				return hasNotUnderbarInAppName(key, targetApp);
			}
		} catch (ControlledAccessException e) {
//			Assert.shouldNeverReachHere("ControlledAccessException", Assert.ON);
			return true;
		}
	}
	
	private static boolean hasNotUnderbarInAppDescription(char key,
			ApplicationDescriptor targetApp) throws ControlledAccessException {
		if (checkNullForAppDescription(targetApp)) 
			return true;
		if (hasNotAtCharUnderBar(
				key, 
				CodeModuleManager.getModuleDescription(
						targetApp.getModuleHandle()).toString()))
			return true;
		return false;
	}
	
	private static boolean hasNotUnderbarInAppName(char key,
			ApplicationDescriptor targetApp) throws ControlledAccessException {
		if (checkNullForAppName(targetApp)) return true;
		if (hasNotAtCharUnderBar(key, targetApp.getName())) return true;
		return false;
	}
	
	static boolean hasNotAtCharUnderBar(char key, String src) {
		try {
			if ((HotkeyCalculator.getAtCharUnderBar(src) == (key)))
				return false;
		} catch (NotUnderbarExcetion e) {
			return true;
		} catch (InitUnderbarException e) {
			return true;
		}
		return true;
	}
	
	private static boolean checkNullForAppDescription(
			ApplicationDescriptor targetApp) throws ControlledAccessException {
		Object description = CodeModuleManager.getModuleDescription(targetApp.getModuleHandle());
		if (targetApp == null || description == null || description.toString() == null)
			return true;
		return false;
	}

	private static boolean checkNullForAppName(ApplicationDescriptor targetApp)
			throws ControlledAccessException {
		if (targetApp == null || targetApp.getName() == null
				|| targetApp.getName().toString() == null)
			return true;
		return false;
	}
	
	static boolean isRimApp(ApplicationDescriptor targetApp) {
		return CodeModuleManager.getModuleVendor(targetApp.getModuleHandle())
				.regionMatches(true, 0, "Research", 0, 8);
	}
}